const configs = require('../config');
const wechat = {
  getUserInfo: require('../wechat/openApi/userInfo/userInfo').getUserInfo,
  login: require('../wechat/openApi/login/login').login,
  getSystemInfo: require('../wechat/device/systemInfo').getSystemInfo,
  request: require('../wechat/network/request'),
  setStorage: require('../wechat/storage/storage').setStorage,
  getStorage: require('../wechat/storage/storage').getStorage
};

const Rx = require('../../bubaocloud/library/reactivex/rx.js');
let app = getApp();
let isConnectSocket, isInitBubble, lock, loginLock, firstLoginObservable;

const loginFromServer = () => {
  return new Promise((resolve, reject) => {
    wechat.login().then((loginInfo) => {
      wechat.getUserInfo({
        
      }).then((userInfo) => {
        userInfos = userInfo;
        wechat.getSystemInfo().then((systemInfo) => {
          let wxUserInfo = userInfo.userInfo;
          let http = request({
            url: `${configs.host.rest}api/WxLogin/login`,
            data: {
              Code: loginInfo.code,//发送code
              Model: systemInfo.model,//手机型号
              Language: systemInfo.language,//微信设置的语言
              WechatVersion: systemInfo.version,//微信版本号
              Version: 'wx_2.0',//小程序版本号
              NickName: wxUserInfo.nickName,//昵称
              Gender: wxUserInfo.gender,//性别
              City: wxUserInfo.city,//城市
              Province: wxUserInfo.province,//省份
              Country: wxUserInfo.country,//国家
              AvatarUrl: wxUserInfo.avatarUrl,//头像
              RawData: userInfo.rawData,//用于计算签名
              Signature: userInfo.signature,//用于校验用户信息。
              EncryptedData: userInfo.encryptedData,//包括敏感数据在内的完整用户信息的加密数据
              Iv: userInfo.iv,//加密算法的初始向量
              wxtypeID: configs.wxTypeId, //小程序id
              InviteCode: getInviteCode(true) //邀请码
            },
            method: 'POST'
          }).then((success) => {
            if (success.IsFirstLogin && app.appOptions.query && app.appOptions.query.userId) {
              wx.reportAnalytics('new_user_from', {
                from: app.appOptions.query.userId,
              });
              let sceneRecord = request({
                url: `${configs.host.rest}api/package/optimize/sceneShare`,
                header: {
                  Authorization: `Client ${success.AuthKey}`
                },
                data: {
                  SceneType: app.appOptions.scene,
                  FromUserId: app.appOptions.query.userId,
                  UserId: success.UserId,
                  DateCreated: '',
                  Remark: ''
                },
                method: 'POST',
                success: (res) => {
                  console.log('记录成功')
                },
                fail: () => {
                  console.log('记录失败')
                }
              })
            }

            userInfos.userId = success.UserId;
            userInfos.openId = success.OpenId;
            let authKey = configs.develop ? 'devClient' : 'client';
            let userKey = configs.develop ? 'devUserInfos' : 'userInfos';
            wechat.setStorage({
              key: authKey,
              data: success.AuthKey
            });
            wechat.setStorage({
              key: userKey,
              data: userInfos
            })
            getSessionFromServer(`Client ${success.AuthKey}`).then(resolve, reject);
            loginLock = false;
          }, (err) => {
            http.unsubscribe()
          }).then(() => {
            http.unsubscribe()
          });

        }, (err) => {
          console.error(err);
        });

      }, (err) => {
        console.error(err)
      });

    }, (err) => {
      console.error(err);
    });

  });
}

const getSessionFromServer = (authKey) => {
  return new Promise((resolve, reject) => {
    let http = request({
      url: `${configs.host.rest}api/SessionKey/Get?shortToken=false`,
      header: {
        Authorization: authKey
      }
    }).then((res) => {
      app.session = res.SessionKey;
      
      if (firstLoginObservable) {
        Rx.subject(firstLoginObservable).success(res);
        firstLoginObservable = null;
      }
      InitBubble(res.SessionKey);//泡泡初始
      // connectSocket(res.SessionKey);//socket连接
      timer();
      http.unsubscribe();
      resolve(res.SessionKey);
    }, reject);

  });
}

const getInviteCode = (isGcode = false) => {
  const G_SCENE_KEY = configs.develop ? 'DEV_SCENE_CODE' : 'G_SCENE_CODE';
  //scene code 只统计用户第一次进入小程序的invite code 以后都用次，直到删除重新打开。
  const gCode = wx.getStorageSync(G_SCENE_KEY);
  if (isGcode) {
    const gCode = wx.getStorageSync(G_SCENE_KEY);
    if (gCode) {
      return gCode;
    }
  }

  let scene = '';
  const appOptions = app.appOptions;
  const hasObjValue = (obj) => {
    //判断对象是否有值
    if (typeof obj !== "object" || !obj) return false;
    for (let i in obj) {
      return true;
    }
    return false;
  }

  if (appOptions.query.scene) {
    scene = (appOptions.query.scene).split('_');
    scene = scene[0] == 'scode' ? scene[1] : null;
  }

  switch (parseInt(appOptions.scene, 10)) {
    case 1011:
    case 1012:
    case 1013:
    case 1037:
      if (appOptions.scene == "1037" && appOptions.referrerInfo) {
        //如果传socde则记录scode 否则记录appId
        let extraData = appOptions.referrerInfo.extraData;
        let extraDataType = typeof (extraData);
        if (extraDataType == 'string') {
          //如果是模拟器（string）尝试json parse 一次
          extraData = JSON.parse(extraData);
        }

        if (hasObjValue(extraData)) {
          scene = extraData['scode'] || appOptions.referrerInfo.appId;
        } else {
          scene = appOptions.referrerInfo.appId || '';
        }
      }
      break;
    case 1047:
    case 1048:
    case 1049:
      if (appOptions.referrerInfo && typeof (appOptions.referrerInfo.extraData) === 'string') {
        scene = JSON.parse(app.appOptions.referrerInfo.extraData);
        scene = scene['scode'] || '';
      }
      break;
    default:
      scene = '';
  }

  if (scene && scene !== '') {
    wx.setStorageSync(G_SCENE_KEY, scene)
  }

  return scene;
}

const InitBubble = (sessionKey) => {
  if (isInitBubble || lock) return;
  lock = true;
  const scene = getInviteCode();

  let http = request({
    url: `${configs.host.rest}/api/Bubble`,
    header: {
      Authorization: `SessionKey ${sessionKey}`
    },
    data: {
      code: scene
    },
    method: 'get'
  })
    .then(res => {
      app.bubbleConfig = res;
      if (app.bubbleObservable) Rx.subject(app.bubbleObservable).success(res);

      lock = false
      isInitBubble = true;
    }, () => {
      lock = false
      http.unsubscribe();
    })
};

/**
 * @desc 基础库 1.7.0 之前，一个微信小程序同时只能有一个 WebSocket 连接，如果当前已存在一个 WebSocket 连接，会自动关闭该连接，并重新创建一个 WebSocket 连接。基础库版本 1.7.0 及以后，支持存在多个 WebSokcet 连接，每次成功调用 wx.connectSocket 会返回一个新的 SocketTask。
 * 
 */
const connectSocket = (sessionKey) => {
  return new Promise((resolve, reject) => {
    if (isConnectSocket) return resolve();
    wx.connectSocket({
      url: configs.host.socket,
      header: {
        Authorization: `SessionKey ${sessionKey}`
      },
      method: 'get',
      success: (res) => {
        resolve(res);
        isConnectSocket = true;
      },
      fail: (err) => {
        console.log(22, err);
        reject(err);
      }
    })
  })
};

const getFirstLoginSession = () => {
  return new Promise((resolve, reject) => {
    firstLoginObservable = Date.parse(new Date());
    Rx.observable(firstLoginObservable)
      .then(res => {
        let session = res ? res.SessionKey : app.session;
        resolve(session);
      })
  })
}

let request;
const login = (that) => {
  return new Promise((resolve, reject) => {
    /**
     * @desc 修复第一次登陆请求无法获取到sessionKey问题
     * @author wqs
     * @dateTime 2018年4月11日16:28:35
     * @version v1.0.3
     */


    if (loginLock) {
      getFirstLoginSession()
        .then(res => {
          resolve(res);
        })
    } else {
      loginLock = true;

      wx.reportAnalytics('xiaochengxuhuanliang', {
        from: getInviteCode(),
      });

      if (that) {
        app = that;
        request = wechat.request.bind(that).request;
      } else {
        request = wechat.request.request;
      }

      let authKeyTxt = configs.develop ? 'devClient' : 'client';
      wechat.getStorage(authKeyTxt)
        .then((authKey) => {
          loginLock = false;
          if (authKey) {
            getSessionFromServer(`Client ${authKey.data}`)
              .then(resolve, reject);
          } else {
            loginFromServer()
              .then(resolve, reject);
          }
        }, () => {
          loginFromServer()
            .then(resolve, reject);
        });
    }
  });

}

const getSession = () => {
  return new Promise((resolve, reject) => {
    if (app.session) {
      resolve(app.session)
    } else {
      login()
        .then(resolve, reject);
    }
  })
}

const timer = () => {
  if (app.timer) {
    clearTimeout(app.timer)
  }
  app.timer = setTimeout(() => {
    getSessionFromServer(`SessionKey ${app.session}`);
  }, 1200000);//20分钟
}

let userInfos;

const getUserInfos = () => {
  let userKey = configs.develop ? 'devUserInfos' : 'userInfos';
  var value = wx.getStorageSync(userKey);
  return value;
};

module.exports = {
  login,
  getSession,
  userInfos,
  getUserInfos,
  connectSocket
}